package com.tnsw.noxnox.downloader;

import java.util.ArrayList;
import java.util.Hashtable;

import org.apache.http.HttpResponse;

import com.tnsw.coreutils.AsyncManager;
import com.tnsw.coreutils.http.THttpBase;
import com.tnsw.coreutils.http.THttpListener;
import com.tnsw.noxnox.db.DBManager;
import com.tnsw.noxnox.db.tables.DownloadProgress;

import android.content.Context;
import android.util.Log;

public class DLBase implements THttpListener {

	private String tag = "DLBase";
	
	protected String firstUrl;
	protected String textStatus;
	protected Context context;
	protected DLInterface dlInterface;
	protected THttpBase currentHttpBase;
	
	private boolean dbEnabled = true;
	private String title;
	protected DownloadProgress dp = new DownloadProgress();
	protected Hashtable<String, String> hashStdAttrs;
	
	private long max;
	private int currentPosition;
	protected boolean isMetaDataOK = false;
	
	public DLBase(Context context, String firstUrl) {
		this.context = context;
		this.firstUrl = firstUrl;
		this.hashStdAttrs = new Hashtable<String, String>();
	}
	
	public void setTitle(String title) {
		this.title = title;
	}
	
	public String getTitle() {
		return(this.title);
	}
	
	public void setDBEnableStatus(boolean enable) {
		this.dbEnabled = enable;
	}
	
	public boolean getDBEnableStatus() {
		return(this.dbEnabled);
	}
	
	public DownloadProgress getDownloadProgressRecord() {
		return(this.dp);
	}
	
	public String getFirstUrl() {
		return(this.firstUrl);
	}
	
	public THttpBase getCurrentHttpBase() {
		return(this.currentHttpBase);
	}
	
	public void setTextStatus(String str) {
		this.textStatus = str;
	}
	
	public int getCurrentPosition() {
		return(this.currentPosition);
	}
	
	public void setCurrentPosition(int i) {
		this.currentPosition = i;
	}
	
	public void setMax(long max) {
		this.max = max;
	}
	
	public long getMax() {
		return(this.max);
	}
	
	public String getTextStatus() {
		return(this.textStatus);
	}
	
	public void setDLInterface(DLInterface inf) {
		this.dlInterface = inf;
	}
	
	public void doit() {
		DBManager dbm = DBManager.getInstance(this.context);
		this.dp.primarykey = dbm.getNewPrimarykey();

	}
	
	public void pause() {
		if (this.currentHttpBase != null) {
			this.currentHttpBase.pause();
		} else {
			Log.w(tag, "Cannot pause() - currentHttpBase == null");
		}
	}
	
	public void stop() {
		if (this.currentHttpBase != null) {
			this.currentHttpBase.stop();
		} else {
			Log.w(tag, "Cannot stop() - currentHttpBase == null");
		}
	}
	
	public void resume() {
		if (this.currentHttpBase != null) {
			this.currentHttpBase.resume();
		} else {
			Log.w(tag, "Cannot resume() - currentHttpBase == null");
		}
	}
	
	public void cancel(boolean mayInterruptIfRunning) {
		if (this.currentHttpBase != null) {
			this.currentHttpBase.cancel(mayInterruptIfRunning);
		} else {
			Log.w(tag, "Cannot cancel() - currentHttpBase == null");
		}
	}

	@Override
	public void onProgressUpdate(THttpBase sender, Integer[] values) {
		this.currentHttpBase = sender;
	}

	@Override
	public void onPostExecute(THttpBase sender, Long result) {
		this.currentHttpBase = sender;
		
		if ( (sender.getSessionName().equals("metadata")) && (this.isMetaDataOK == false) ) {
			// Finished metadata stream and cannot find Metadata
			if (this.dlInterface != null) {
				if (sender.getHttpResponse() != null) {
					if (sender.getHttpResponse().getStatusLine().getStatusCode() == 200) {
						this.dlInterface.onError(this, false, "Cannot go further from metadata", null);		
					} else {
						this.dlInterface.onError(this, false, "Get HTTP response != 200 from metadata", null);
					}
					
				} else {
					this.dlInterface.onError(this, false, "Cannot get HTTP response from metadata", null);
				}
				
				return;
			}
		}
		
		DBManager dbm = DBManager.getInstance(this.context);
		
		if (sender.getSessionName().equals("metadata")) {
			
			if (this.getDBEnableStatus() == true) {
								
				//this.dp.primarykey = dbm.getNewPrimarykey();
				this.dp.url = this.firstUrl;
				this.dp.status = 1;
				this.dp.title = this.getTitle();
						
				dbm.insertDownloadProgress(this.dp);
			}
			
		} else if (sender.getSessionName().equals("binary")) {
			if (sender.getHttpResponse() != null) {
				if (sender.getHttpResponse().getStatusLine().getStatusCode() == 200) {
					this.dp.status = 2;
					dbm.updateDownloadProgress(this.dp, true);
				} else {
					if (this.dlInterface != null) {
						int statusCode = sender.getHttpResponse().getStatusLine().getStatusCode();
						this.dlInterface.onError(this, false, "Binary HTTP response error (" + statusCode + ")", null);
					}
				}
				
			} else {
				if (this.dlInterface != null) {
					this.dlInterface.onError(this, false, "HttpResponse from binary is null", null);
				}
			}
		}
	}

	@Override
	public void onNewLineFetchBG(THttpBase sender, String line) {
		this.currentHttpBase = sender;
		
		if (this.dlInterface != null) {
			this.dlInterface.onProgressBG(this);
		}
	}

	@Override
	public void onReceiveResponseBG(THttpBase sender) {
		this.currentHttpBase = sender;
		
		if (this.dlInterface != null) {
			this.dlInterface.onStartedBG(this);
		}
		
		if (sender.getSessionName().equals("metadata")) {
			
			
		} else if (sender.getSessionName().equals("binary")) {
			if (sender.getHttpResponse() != null) {
				HttpResponse response = sender.getHttpResponse();
				if (response.getStatusLine().getStatusCode() == 200) {
					this.dp.content_length = (int) sender.getContentLength();
					this.dp.filename = sender.getCurrentBinaryfileName();
					Log.d(tag, "filename=" + this.dp.filename);
					
					if (this.hashStdAttrs.containsKey("content-type") == false) {
						this.hashStdAttrs.put("content-type", response.getFirstHeader("Content-Type").getValue());
					}
					
					DBManager dbm = DBManager.getInstance(this.context);
					dbm.updateDownloadProgress(this.dp, true);
					dbm.updateDownloadAttribute(null, this.dp.primarykey, this.hashStdAttrs);
					
					
				}
			}
		}
	}
	
	public boolean isPaused() {
		if (this.currentHttpBase != null) {
			return(this.currentHttpBase.isPaused());
		} else {
			return(false);
		}
	}
	
	public boolean isStopped() {
		if (this.currentHttpBase != null) {
			return(this.currentHttpBase.isStopped());
			
		} else {
			return(false);
		}
	}

	@Override
	public void onBinaryReadBG(THttpBase sender, byte[] b) {
		this.currentHttpBase = sender;
		
		if (sender.getSessionName().equals("binary")) {
			this.dp.current_position = (int) sender.getCurrentPosition();
			DBManager dbm = DBManager.getInstance(this.context);
			dbm.updateDownloadProgress(this.dp, false);
			
			if (this.dlInterface != null) {
				this.dlInterface.onProgressBG(this);
			}
		}
	}

}
